#include "cwebsocket.h"

#include <QNetworkProxy> // 引入 QNetworkProxy

CWebSocket::CWebSocket(QObject *parent)
    : QObject{parent}
{
    // 连接 QWebSocket 的信号到本类的槽函数
    connect(&m_webSocket, &QWebSocket::connected, this, &CWebSocket::onConnected);
    connect(&m_webSocket, &QWebSocket::disconnected, this, &CWebSocket::onDisconnected);
    connect(&m_webSocket, &QWebSocket::textMessageReceived, this, &CWebSocket::onTextMessageReceived);
    connect(&m_webSocket, &QWebSocket::binaryMessageReceived, this, &CWebSocket::onBinaryMessageReceived);

    // 注意: Qt 6 中 QWebSocket::error 信号已弃用，应使用 errorOccurred
    connect(&m_webSocket, &QWebSocket::errorOccurred, this, &CWebSocket::onErrorOccurred);

    connect(&m_webSocket, &QWebSocket::stateChanged, this, &CWebSocket::onStateChanged);

    // 处理 SSL 错误信号 (对于 wss:// 连接很重要)
    connect(&m_webSocket, &QWebSocket::sslErrors, this, &CWebSocket::onSslErrors);
}


CWebSocket::~CWebSocket()
{
    // 析构时确保断开连接
    if (m_webSocket.state() != QAbstractSocket::UnconnectedState) {
        m_webSocket.close(QWebSocketProtocol::CloseCodeNormal, "Client shutting down");
    }
    qInfo() << "WebSocketClient: 销毁";
}

void CWebSocket::connectToServer(const QUrl &url)
{
    if (url.isValid()) {
        m_url = url; // 保存 URL
        qInfo() << "WebSocketClient: 尝试连接到" << url.toString();

        // --- 显式禁用代理 ---
        m_webSocket.setProxy(QNetworkProxy::NoProxy);

        QNetworkRequest request(url);
        // 设置 Janus 子协议 - 这是正确的
        request.setRawHeader("Sec-WebSocket-Protocol", "janus-protocol");

        // --- 处理 WSS (SSL/TLS) 连接 ---
        if (url.scheme().toLower() == "wss") {
            qInfo() << "WebSocketClient: 正在尝试 WSS (安全) 连接。";

            // 重要提示：处理 SSL 错误
            // 1. 确保证书有效：如果服务器使用自签名证书，或者证书链不被系统信任，
            //    连接会失败，并触发 sslErrors 信号。
            // 2. 在生产环境中，你不应该忽略 SSL 错误。你需要确保服务器证书有效，
            //    或者在客户端配置信任特定的 CA 或证书。
            // 3. **仅用于测试目的**，你可以忽略 SSL 错误，但这非常不安全：
            //    connect(&m_webSocket, &QWebSocket::sslErrors, this, [this](const QList<QSslError> &errors){
            //        qWarning() << "WebSocketClient: 发生 SSL 错误 (将忽略):" << errors;
            //        m_webSocket.ignoreSslErrors(errors); // 极不推荐在生产中使用！
            //    });
            // 另一种测试自签名证书的方法（也仅用于测试）：
            // QSslConfiguration sslConfig = m_webSocket.sslConfiguration();
            // sslConfig.setPeerVerifyMode(QSslSocket::VerifyNone); // 禁用证书验证！
            // m_webSocket.setSslConfiguration(sslConfig);

            // 如果你的 Qt 构建没有包含或找不到 OpenSSL 库，WSS 连接也会失败。
            if (!QSslSocket::supportsSsl()) {
                qWarning() << "WebSocketClient: 致命错误 - 此 Qt 构建不支持 SSL (OpenSSL 可能缺失或未正确配置)";
                emit errorOccurred("Qt 不支持 SSL，无法建立 WSS 连接");
                return; // 无法继续
            } else {
                qInfo() << "WebSocketClient: Qt 支持 SSL。OpenSSL 版本:" << QSslSocket::sslLibraryBuildVersionString();
            }
        }

        // 使用包含请求头 (和可能的 SSL 配置) 的 request 对象打开连接
        m_webSocket.open(request);

    } else {
        qWarning() << "WebSocketClient: 无效的 URL:" << url.toString();
        emit errorOccurred("无效的 URL: " + url.toString());
    }

}

void CWebSocket::disconnectFromServer()
{
    m_webSocket.close(QWebSocketProtocol::CloseCodeNormal, "Client requested disconnect");
}

qint64 CWebSocket::sendTextMessage(const QString &message)
{
    if (isConnected()) {
        qDebug() << "WebSocketClient: 发送文本消息:" << message;
        return m_webSocket.sendTextMessage(message);
    } else {
        qWarning() << "WebSocketClient: 发送文本消息失败，未连接";
        return -1; // 或其他表示失败的值
    }
}

qint64 CWebSocket::sendBinaryMessage(const QByteArray &data)
{
    if (isConnected()) {
        qDebug() << "WebSocketClient: 发送二进制消息，大小:" << data.size();
        return m_webSocket.sendBinaryMessage(data);
    } else {
        qWarning() << "WebSocketClient: 发送二进制消息失败，未连接";
        return -1; // 或其他表示失败的值
    }
}

bool CWebSocket::isConnected() const
{
    return m_webSocket.state() == QAbstractSocket::ConnectedState;
}

QAbstractSocket::SocketState CWebSocket::state() const
{
    return m_webSocket.state();
}

QString CWebSocket::errorString() const
{
    return m_webSocket.errorString(); // 获取 QWebSocket 内部的错误描述
}


void CWebSocket::onConnected()
{
    qInfo() << "WebSocketClient: 已成功连接到" << m_url.toString();
    emit connected(); // 发出连接成功的信号
}

void CWebSocket::onDisconnected()
{
    qInfo() << "WebSocketClient: 连接已断开";
    emit disconnected(); // 发出断开连接的信号
}

void CWebSocket::onTextMessageReceived(const QString &message)
{
    qDebug() << "WebSocketClient: 收到文本消息:" << message;
    emit textMessageReceived(message); // 转发收到的文本消息
}

void CWebSocket::onBinaryMessageReceived(const QByteArray &data)
{
    qDebug() << "WebSocketClient: 收到二进制消息，大小:" << data.size();
    emit binaryMessageReceived(data); // 转发收到的二进制数据
}

void CWebSocket::onErrorOccurred(QAbstractSocket::SocketError error)
{
    QString errorStr = m_webSocket.errorString();
    qWarning() << "WebSocketClient: 发生错误:" << error << "-" << errorStr;
    emit errorOccurred(errorStr); // 发出包含错误描述字符串的信号
}

void CWebSocket::onSslErrors(const QList<QSslError> &errors)
{
    QString errorStrings;
    for (const QSslError &error : errors) {
        qWarning() << "WebSocketClient: SSL 错误:" << error.errorString();
        if (!errorStrings.isEmpty()) {
            errorStrings += "; ";
        }
        errorStrings += error.errorString();
    }


    emit errorOccurred("SSL 错误: " + errorStrings);

    // 如果决定不忽略，连接过程通常会失败，并触发 onErrorOccurred
}

void CWebSocket::onStateChanged(QAbstractSocket::SocketState state)
{
    qInfo() << "WebSocketClient: 连接状态改变为" << state;
    emit stateChanged(state); // 发出状态改变信号
}
